﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Threading;

using System.Net.Sockets;
namespace ServerSandboxie
{
    public partial class FormMain : Form
    {
        IPAddress localAddress;
        private List<User> userList = new List<User>();
        private delegate void AddItemToListBoxDelegate(string name);
        NetworkStream ns = null;
        private TcpListener mylistener;
        bool isExit = false;
        string name;
        public FormMain()
        {
            InitializeComponent();
            IPAddress[] addrIp = Dns.GetHostAddresses(Dns.GetHostName());
            localAddress = addrIp[addrIp.Length - 2];
            textBoxServer.Text = localAddress.ToString();
            
        }
        private void buttonListen_Click(object sender, EventArgs e)
        {
            mylistener = new TcpListener(localAddress, 8888);
            mylistener.Start();
            Thread mythread = new Thread(listenconnect);
            mythread.Start();
            buttonListen.Enabled = false;
            buttonStop.Enabled = true;
        }
        private void listenconnect()
        {
            TcpClient client = null;
            while (true)
            {
                try
                {
                    client = mylistener.AcceptTcpClient();
                }
                catch
                {

                    break;
                }
                User user = new User(client);
                Thread threadreceive = new Thread(receive);
                threadreceive.Start(user);
                userList.Add(user);
                //MessageBox.Show(string.Format("[{0}]进入", client.Client.RemoteEndPoint));
            }
        }
        private void receive(object userdata)
        {
            User user = (User)userdata;
            TcpClient client = user.client;
            while (isExit == false)
            {
                string receive = null;
                try
                {
                    receive = user.br.ReadString();
                }
                catch
                {

                    if (isExit == false)
                    {
                        MessageBox.Show(string.Format("与[{0}]失去联系，已终止接收该用户信息", client.Client.RemoteEndPoint));
                        Removeuser(user);
                        removeusername(name);

                    }
                    break;

                }
                string[] splitString = receive.Split(',');
                string sendString = "";
                switch (splitString[0])
                {
                    case "Login":
                        //格式：Login
                        user.userName = splitString[1];
                        name = splitString[1];
                        AddItemToListBox(splitString[1]);
                        sendAllclient(user, receive);
                        MessageBox.Show(string.Format("用户[{0}]登陆", splitString[1]));
                        break;
                    case "Logout":
                        //格式：Logout
                        sendAllclient(user, receive);
                        removeusername(splitString[1]);
                        Removeuser(user);
                        return;
                    case "Talk":
                        //格式：Talk,对话内容
                        string talkstring = splitString[2];
                        sendOneclient(user, "talk," + user.userName + "," + talkstring);
                        foreach (User target in userList)
                        {
                            if (target.userName != splitString[1])
                            {
                                sendOneclient(target, "talk," + user.userName + "," + talkstring);
                            }
                        }
                        AddTalkMessage("[" + splitString[1] + "]" + ":" + receive.Substring(splitString[0].Length + splitString[1].Length + 2));
                        break;
                    default:
                        MessageBox.Show("什么意思啊：" + receive);
                        break;
                }
            }
        }
        private void sendOneclient(User user, string message)
        {
            try
            {
                //将字符串写入网络流，此方法会自动附加字符串长度前缀
                user.bw.Write(message);
                user.bw.Flush();
            }
            catch
            {
                MessageBox.Show(string.Format("向[{0}]发送信息失败",
                    user.userName));
            }
        }
        private void sendAllclient(User user, string message)
        {
            string command = message.Split(',')[0].ToLower();
            if (command == "login")
            {
                for (int i = 0; i < userList.Count; i++)
                {
                    sendOneclient(userList[i], message);
                    if (userList[i].userName != user.userName)
                    {
                        sendOneclient(user, "login," + userList[i].userName);
                    }
                }
            }
            else if (command == "logout")
            {
                for (int i = 0; i < userList.Count; i++)
                {
                    if (userList[i].userName != user.userName)
                    {
                        sendOneclient(userList[i], message);
                    }
                }
            }
        }
        private void Removeuser(User user)
        {
            MessageBox.Show(string.Format("用户[{0}]退出", user.userName));
            userList.Remove(user);
            user.Close();
            //MessageBox.Show(string.Format("当前连接用户数：{0}", userList.Count));
        }
        private delegate void removeusernameDelegate(string username);
        private void removeusername(string username)
        {
            if (listBoxOnline.InvokeRequired)
            {
                removeusernameDelegate d = removeusername;
                listBoxOnline.Invoke(d, username);
            }
            else
            {
                listBoxOnline.Items.Remove(username);
                listBoxOnline.SelectedIndex = listBoxOnline.Items.Count - 1;
            }
        }
        private void AddItemToListBox(string name)
        {
            if (listBoxOnline.InvokeRequired)
            {
                AddItemToListBoxDelegate d = new AddItemToListBoxDelegate(AddItemToListBox);
                listBoxOnline.Invoke(d,new object[]{name});
            }
            else
            {
                listBoxOnline.Items.Add(name);
                listBoxOnline.SelectedIndex = listBoxmessage.Items.Count - 1;
             }
        }
        private delegate void MessageDelegate(string message);
        private void AddTalkMessage(string message)
        {
            if (listBoxmessage.InvokeRequired)
            {
                MessageDelegate d = new MessageDelegate(AddTalkMessage);
                listBoxmessage.Invoke(d, new object[] { message });
            }
            else
            {
                listBoxmessage.Items.Add(message);

            }
        }
        private void buttonStop_Click(object sender, EventArgs e)
        {
            MessageBox.Show("开始停止服务，并依次使用户退出!");
            isExit = true;
            for (int i = userList.Count - 1; i >= 0; i--)
            {
                Removeuser(userList[i]);
                removeusername(name);
            }
            //通过停止监听让myListener.AcceptTcpClient()产生异常退出监听线程
            mylistener.Stop();
            buttonListen.Enabled = true;
            buttonStop.Enabled = false;
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (mylistener != null)
            {
                buttonStop.PerformClick();
            }
        }

    }
}
